//@author A0101056Y

//All the constants used in other classes are 
//declared in this header file
//When you use it, include the namespace, e.g. 
//using namespace SearchConstants

#pragma once 
#include <string>
#include "CommonDataType.h"

using std::string;
using namespace CommonDataType;

const ByteInt SIZE_OF_INDEX_TRANSLATOR = 5; 

namespace SearchConstants {
	con_chr SEARCH_SEP_CHAR_LIST [] = {
		' ', ',', '.', '"',
		'(', ')', '[', ']', '{', '}',
	};
	const pos_int SEARCH_SEP_LIST_CHAR_N = 10;
};

//@author A0083782W
namespace TimeConstants {
	const ByteInt CONST_ARRAY_MAX = 3;
	const ByteInt DURATION_MEMBER = 2;
	
	con_chr SEP_CHAR_LIST[] = {
		' ', ',', '\0', '\n', '\t',
	};
	const ByteInt SEP_CHAR_LIST_N = 5;

	con_chr TIME_SEP_CHAR [] = {
		':'
	};
	const ByteInt TIME_SEP_CHAR_N = 1;

	con_chr DATE_SEP_CHAR[] = {
		'/', '.', '-'
	};
	const ByteInt DATE_SEP_CHAR_N = 3;

	con_chr DURATION_CHAR[] = {
		'-','~'
	};
	const ByteInt DURATION_CHAR_N = 2;
	
	//All the names of the day of the week
	con_str WEEKDAY_LIST[][CONST_ARRAY_MAX] = { 
		{"sunday", "sun"},
		{"monday", "mon"},
		{"tuesday", "tue", "tues"},
		{"wednesday", "wed", "wednes"},
		{"thursday", "thu", "thurs"},
		{"friday", "fri"},
		{"saturday", "sat", "satur"}
	};
	const ByteInt WEEKDAY_LIST_N = 7;

	//The O'clock string
	con_str OCLOCK[] = {
		"o'clock",
		"oclock"
	};
	const ByteInt OCLOCK_N = 2;
	
	//The list of names of month
	con_str MONTH_LIST[][CONST_ARRAY_MAX] = {
		{},
		{"january", "jan"},
		{"feburary", "feb"},
		{"march", "mar"},
		{"april", "apr"},
		{"may"},
		{"june", "jun"},
		{"july", "jul"},
		{"august", "aug"},
		{"september", "sep"},
		{"october", "oct" },
		{"november", "nov"},
		{"december", "dec"}
	};
	const ByteInt MONTH_LIST_N = 13;

	//The list of preposition words. It will be needed to intelligently sense the time and date.
	con_str PREP[] = {
		"at", "before", "after", "aft", "bef", "on",
		"by"
	};
	const ByteInt PREP_N = 7;

	con_str TODAY = "today";

	//Strings that indicate tommorrow
	con_str TOMORROW[] = {"tommorrow","tmr"};
	const ByteInt TOMORROW_N = 2;

	//Strings that indicate am or pm
	con_str AM_PM[][CONST_ARRAY_MAX] = {
		{},
		{"am", "a.m."},
		{"pm", "p.m."}
	};

	//Strings that indicate the time is set with a am
	con_str MORNING_STRING[] = {
		"morning",
		"noon"
	};
	const ByteInt MORNING_STRING_N = 2;

	//Strings that indicate the time is set at a pm
	con_str AFTERNOON_STRING[] = {
		"afternoon",
		"evening",
		"night"
	};
	const ByteInt AFTERNOON_STRING_N = 3;

	con_str STRING_EVERYDAY[]  = { 
		"everyday",
		"everydays",
		"daily"
	};
	const ByteInt STRING_EVERYDAY_N = 3;

	con_str STRING_WEEK[] = {
		"week",
		"weeks"
	};
	const ByteInt STRING_WEEK_N = 2;

	con_str STRING_DAY[] = {
		"day",
		"days"
	};
	const ByteInt STRING_DAY_N = 2;

	con_str STRING_MONTH[] = {
		"month",
		"months"
	};
	const ByteInt STRING_MONTH_N = 2;

	con_str WORD_TO = "to";
	con_str STRING_EVERY[] = {
		"every", "each"
	};
	const ByteInt STRING_EVERY_N = 2;

	con_str STRING_WEEKLY = "weekly";
	con_str STRING_MONTHLY = "monthly";

	con_str STRING_NEXT = "next";
	con_str STRING_THIS = "this";
	con_str STRING_COMING = "coming";

	//These string are used to promote a number to a time string.
	con_str TIME_PROMOTE_STRING = ":00";
	con_str TIME_AM_PROMOTE_STRING = ":00am";
	con_str TIME_PM_PROMOTE_STRING = ":00pm";

	con_str DATE_EMPTY_DAY = "0";
	
	//These constants are used to recognise a time. Avoid changing them
	const ByteInt AM_PM_N = 3;
	const ByteInt TIME_STRING_LENGTH_4 = 4;
	const ByteInt TIME_STRING_LENGTH_5 = 5;
	const ByteInt COLON_POS_1 = 1;
	const ByteInt COLON_POS_2 = 2;
	const ByteInt MINUTES_STRING_SIZE = 2;
	const ByteInt MAX_NUM_YEAR_PART = 3;
	const ByteInt MIN_NUM_YEAR_PART = 2;
	const ByteInt YEAR_STRING_MIDDLE = 1;
	const ByteInt YEAR_STRING_FIRST = 0;
	const ByteInt YEAR_STRING_LAST = 2;
	const ByteInt YEAR_STRING_MAX_LENGTH = 4;
	const ByteInt YEAR_STRING_NORMAL_LENGTH = 2;
	const ByteInt YEAR_STRING_MIN_LENGTH = 1;
	const pos_int THIS_CENTURY = 20;
	

	//These constants tells if a time is legal. Avoid changing
	const pos_int MAX_HOUR = 23;
	const pos_int MAX_MINUTE = 59;
	const pos_int MAX_HALF_HOUR = 12;
	const pos_int MAX_FEB_DAY = 28 ;
	const pos_int MAX_FEB_LEAP_DAY = 29;
	const pos_int MAX_DAY = 30;
	const pos_int MAX_DAY_PLUS = 31;
	const pos_int MAX_MONTH = 12;
	const pos_int MAX_YEAR = 99;
	const pos_int MAX_WEEK = 7;
	const pos_int FOUR_DIGIT_YEAR = 2000;

	//These are constants for duration check
	const ByteInt DURATION_PARTS = 2;

	//<- constants list ends here

	enum class WeekDay {
		SUNDAY = 0,
		MONDAY = 1,
		TUESDAY = 2,
		WEDNESDAY = 3,
		THURSDAY = 4,
		FRIDAY = 5,
		SATURDAY = 6,
		UNCLEAR = 7
	};

	enum class Month {
		UNDEFINED = 0,
		JANUARY = 1,
		FEBURARY = 2,
		MARCH = 3,
		APRIL = 4,
		MAY = 5,
		JUNE = 6,
		JULY = 7,
		AUGUST = 8,
		SEPTEMBER = 9,
		OCTOBER = 10,
		NOVEMBER = 11,
		DECEMBER = 12
	};
};

namespace CommandConstants {
	const ByteInt CMD_MAX = 4;
	con_str KEYWORD_LIST[][CMD_MAX] = { 
		{},
		{"add","new"}, 
		{"delete", "del"},
		{"change", "modify"},
		{"search", "find","display","show"},
		{"undo"},
		{"help"},
		{"setting","config"},
		{"mark"},
		{"exit","quit"},
		{"clear"},
		{"save"},
	};
	const ByteInt KEYWORD_LIST_N = 12;	
	
	con_str STRING_REMINDED = "reminded";
	con_str STRING_NOT = "not";
	con_str STRING_DONE = "done";
	con_str STRING_MISSED = "missed";
	con_str STRING_SFLOATING = "floating";
	con_str STRING_FAVOURITE = "favourite";
	con_str STRING_REPEATABLE = "repeatable";

	con_chr CHARACTER_SPACE = ' ';

	con_chr CMD_SEP_CHAR[] = {'\\'};
	const ByteInt CMD_SEP_CHAR_N = 1;
	
	con_chr TAG_SEP_CHAR[] = {' '};
	const ByteInt TAG_SEP_CHAR_N = 1;

	con_chr DEL_SEP_CHAR_LIST[] = {
		',', ';', '/', '.',
	};
	const pos_int DEL_SEP_CHAR_LIST_N = 4;

	con_chr DEL_PARAMETER_ALLOWED_CHAR_LIST [] = {
		'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
		't', 'o', '-', '~'
	};
	const ByteInt DEL_PARAMETER_ALLOWED_CHAR_LIST_N = 14;

	const ByteInt ADD_PARAMETERS_SIZE = 5;

	const ByteInt SEARCH_PARAMETER_SIZE = 3;
	const ByteInt SEARCH_POS_DESC = 0;
	const ByteInt SEARCH_POS_TIME = 1;
	const ByteInt SEARCH_POS_TAGS = 2;
	const ByteInt SEARCH_FLAG_MAX_SIZE = 2;
	const ByteInt SEARCH_FLAG_MIN_SIZE = 1;
};